package display
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.geom.Point;
	
	import mx.core.FlexSprite;
	import mx.graphics.IStroke;
	
	import util.DisplayUtil;

	/**
	 * 墙壁，一般房屋就四个墙壁，每个墙壁可以有多条FreeLine组成
	 * 每个房间的墙壁都是独有的，不会共享
	 * @see display.FreeLine
	 */
	public class Wall extends FlexSprite
	{
		private var _freeLines:Array;
		
		private var _stroke:IStroke;
		
		/**
		 * 主动split的freeLine,不需要被动更新
		 */
		private var splitingLine:FreeLine;
		
		public function Wall()
		{	
			this.addEventListener(Event.ADDED_TO_STAGE, onStageAdded);
		}
		
		public function validate():void
		{
			if(freeLines != null)
			{
				draw();
			}
		}
		
		private function onStageAdded(event:Event):void
		{
			this.stage.addEventListener("freeLineSplited", onLineSplited);
		}
		
		private function onLineSplited(event:Event):void
		{	
			if(splitingLine == event.target)
			{
				return;
			}
			if(!freeLines)
			{
				return;
			}
			if(freeLines.indexOf(event.target) < 0)
			{
				return;
			}
			trace("splited line: " + event.target);
			var line:FreeLine = event.target as FreeLine;
			if(line.splitedLine != null)
			{
				freeLines.push(line.splitedLine);
			}
			draw();
		}
		
		public function refresh():void
		{
			var length:int = freeLines.length;
			for(var i:int = 0; i < length; i++)
			{
				FreeLine(freeLines[i]).refresh();
			}
		}
		
		protected function draw():void
		{
			DisplayUtil.removeAll(this);
			var length:int = freeLines.length;
			for(var i:int = 0; i < length; i++)
			{
				addChild(freeLines[i] as DisplayObject);
			}
		}
		
		/**
		 * 拆分Wall,如果是在该地方拆分，则返回新生成的两个Wall，
		 * 否则返回方位
		 * lt:表示上方或者左边
		 * rb:表示下方或者右边
		 * wall的split比较特殊，并没有像FreeLine的split一样，在原有的元素
		 * 上split，而是新生成两个wall，原有的wall保持不变
		 * @see display.FreeLine#split()
		 */
		public function split(position:Number, direction:String):Object
		{
			var splitedLine:FreeLine;
			var newLine:FreeLine;
			var leftLines:Array = [];
			var rightLines:Array = [];
			for(var i:int = freeLines.length - 1; i >= 0; i--)
			{
				splitingLine = FreeLine(freeLines[i]);
				var result:Object = splitingLine.split(position, direction);
				if(result is FreeLine)
				{
					splitedLine = FreeLine(freeLines[i]);
					newLine = result as FreeLine;
					continue;
				}
				//把lines分成两大阵营,1个阵营仍然呆在freeline中，另一个则放在splitedLine中
				if(result == "lt")
				{
					leftLines.push(freeLines[i]);
				}
				else
				{
					rightLines.push(freeLines[i]);
				}
			}
			splitingLine = null;
			if(splitedLine == null)
			{
				//没有splitedLine，则看看是否已经分过了
				var testPoint:Point = getPointAtDirection(leftLines, "rb");	
				var match:Boolean = direction == "horizontal" ? 
				    testPoint.x == position : testPoint.y == position;
				if(match)
				{
					testPoint = getPointAtDirection(rightLines, "lt");	
					match = direction == "horizontal" ? 
					    testPoint.x == position : testPoint.y == position;
				}
				if(!match)
				{
					return leftLines.length > 0 ? "lt" : "rb";
				}
			}
			if(splitedLine)
			{
				leftLines.push(splitedLine);
			}			
			
			//这里生成新的leftWall是保证拆分的时候不影响已有的wall
			var newLeftWall:Wall = new Wall();
			newLeftWall.freeLines = leftLines;
			
			var newRightWall:Wall = new Wall();
			if(newLine)
				rightLines.unshift(newLine);
			newRightWall.freeLines = rightLines;
			return [newLeftWall, newRightWall];
		}
		
		public function getPointAtDirection(lines:Array, direction:String):Point
		{
			var p:Point = direction == "lt" ? new Point(int.MAX_VALUE, int.MAX_VALUE)
			  : new Point(0, 0);
			for(var i:int = lines.length - 1; i >= 0; i--)
			{
				var line:FreeLine = lines[i] as FreeLine;
				if(direction == "lt")
				{
					var comparePoint:Point = line.leftTopPoint;
					if(comparePoint.x < p.x || comparePoint.y < p.y)
					{
						p = comparePoint;
					}
				}
				else
				{
					comparePoint = line.rightBottomPoint;
					if(comparePoint.x > p.x || comparePoint.y > p.y)
					{
						p = comparePoint;
					}
				}
			}
			return p;
		}
		
		public function scale(oldSize:Point, newSize:Point):void
		{
			var length:int = freeLines.length;
			for(var i:int = 0; i < length; i++)
			{
				FreeLine(freeLines[i]).scale(oldSize, newSize);
			}
		}
		
		public function get freeLines():Array
		{
			return _freeLines;
		}

		public function set freeLines(v:Array):void
		{
			_freeLines = v;
			validate();
		}

		public function get stroke():IStroke
		{
			return _stroke;
		}

		public function set stroke(v:IStroke):void
		{
			_stroke = v;
			var length:int = freeLines.length;
			for(var i:int = 0; i < length; i++)
			{
				FreeLine(freeLines[i]).stroke = v;
			}
		}

	}
}